EC2 に IAM アクセスキー を保存して S3 の API をコールしたとき CloudTrail のイベントログの記録内容を調べてみた
IAM アクセスキーが保存された EC2 を捜索する方法を考えていました。
手始めに CloudTrail のイベントログにどのようなイベントが記録されるか把握しておきたいと思い、今回の検証では IAM アクセスキーを作成し EC2 に保存し、IAM アクセスキーの認証情報を使って S3 の API をコールしたとき、CloudTrail のイベントログにはどのように記録されるのかを確認することを目的とします。CloudTrail のログの内容の記録を残すついでに検証内容を紹介します。
確認結果
EC2 から S3 の API(ListBuckets
)をコールしたときの CloudTrail のイベントログより
- IAM ロールでの API コールは EC2 のインスタンス ID が記録され特定が容易
- IAM アクセスキーからの API コールは EC2 の Public IP か Private IP から EC2 を特定できる
- ただし、IAM アクセスキー + NAT Gateway 経由は NAT Gateway の EIP がソースとして記録される
- NAT Gateway 配下に複数台 EC2 がある場合は1つのイベントログから EC2 の特定は困難
Credential | サブネット | VPC Endpoint Gateway Type | ユーザー名の表示 | ソース IP の表示 |
---|---|---|---|---|
IAM ロール | Public | なし | EC2 の インスタンスID | EC2 の Public IP |
IAM ロール | Private | なし | EC2 の インスタンスID | NAT Gateway の EIP |
IAM アクセスキー | Public | なし | IAM ユーザー名 | EC2 の Public IP |
IAM アクセスキー | Private | なし | IAM ユーザー名 | NAT Gateway の EIP |
IAM アクセスキー | Public | あり | IAM ユーザー名 | EC2 の Private IP |
IAM アクセスキー | Private | あり | IAM ユーザー名 | EC2 の Private IP |
IAM ロール編
IAM アクセスキーを保存した EC2 と比較するために IAM ロールの場合のイベントログの記録内容を確認します。
AmazonS3ReadOnlyAccess
ポリシーをアタッチした IAM ロールを作成し EC2 に設定しました。
パブリックサブネットの EC2 の場合
パブリックサブネットで起動した EC2 から Internet Gateway を経由して S3 バケットへアクセスします。VPC エンドポイントは設定していません。
[ec2-user@ip-10-0-1-232 .aws]$ aws s3 ls | grep abashiri 2022-04-08 10:37:53 abashiri-image 2022-04-08 10:37:52 abashiri-image-log
CloudTrail から ListBuckets
イベントを確認します。ユーザー名から EC2 インスタンスの ID を確認できます。
個人的な見どころ
- アクセス元の EC2 のインスタンス ID (
i-0f48040475b4f3464
)を確認できる - IAM ロール名(
s3readonly
)を確認できる - アクセス元のソースIP(
52.197.156.173
)は EC2 のパブリック IP であった
{ "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROAQ4BT4DHFO2FNYZAOZ:i-0f48040475b4f3464", "arn": "arn:aws:sts::123456789012:assumed-role/s3readonly/i-0f48040475b4f3464", "accountId": "123456789012", "accessKeyId": "ASIAQ123456789012345", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROAQ4BT4DHFO2FNYZAOZ", "arn": "arn:aws:iam::123456789012:role/s3readonly", "accountId": "123456789012", "userName": "s3readonly" }, "webIdFederationData": {}, "attributes": { "creationDate": "2022-06-28T00:11:43Z", "mfaAuthenticated": "false" }, "ec2RoleDelivery": "2.0" } }, "eventTime": "2022-06-28T00:20:59Z", "eventSource": "s3.amazonaws.com", "eventName": "ListBuckets", "awsRegion": "ap-northeast-1", "sourceIPAddress": "52.197.156.173", "userAgent": "[aws-cli/1.18.147 Python/2.7.18 Linux/5.10.118-111.515.amzn2.aarch64 botocore/1.18.6]", "requestParameters": { "Host": "s3.ap-northeast-1.amazonaws.com" }, "responseElements": null, "additionalEventData": { "SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "kEvE5BsV+VcwE9WiDT1LJpJNXqAfzDMPGV8WkbM3dutCE5XfIbXGvM9E6gIeGYjyf6e+RvGkswg=", "bytesTransferredOut": 5391 }, "requestID": "9JWF4V4M8CPX3PXE", "eventID": "40279e48-60fc-4a2a-9742-3d23cff08dac", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "123456789012", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.ap-northeast-1.amazonaws.com" } }
EC2 のパブリック IP アドレス
プライベートサブネットの EC2 の場合
プライベートサブネットで起動した EC2 から NAT Gateway を経由して S3 バケットへアクセスします。VPC エンドポイントは設定していません。
IAM ロールに付与された権限で S3 バケットの一覧を取得(ListBuckets
)することができました。
[ec2-user@ip-10-0-17-225 .aws]$ aws s3 ls | grep abashiri 2022-04-08 10:37:53 abashiri-image 2022-04-08 10:37:52 abashiri-image-log
CloudTrail から ListBuckets
イベントを確認します。ユーザー名から EC2 インスタンスの ID を確認できます。
個人的な見どころ
- アクセス元の EC2 のインスタンス ID (
i-0989653702d4b4d51
)を確認できる - IAM ロール名(
s3readonly
)を確認できる - アクセス元のソースIP(
54.150.188.89
)は NAT Gateway の EIP であった
{ "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROAQ4BT4DHFO2FNYZAOZ:i-0989653702d4b4d51", "arn": "arn:aws:sts::123456789012:assumed-role/s3readonly/i-0989653702d4b4d51", "accountId": "123456789012", "accessKeyId": "ASIAQ123456789012345", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROAQ4BT4DHFO2FNYZAOZ", "arn": "arn:aws:iam::123456789012:role/s3readonly", "accountId": "123456789012", "userName": "s3readonly" }, "webIdFederationData": {}, "attributes": { "creationDate": "2022-06-27T09:38:14Z", "mfaAuthenticated": "false" }, "ec2RoleDelivery": "2.0" } }, "eventTime": "2022-06-27T09:42:21Z", "eventSource": "s3.amazonaws.com", "eventName": "ListBuckets", "awsRegion": "ap-northeast-1", "sourceIPAddress": "54.150.188.89", "userAgent": "[aws-cli/1.18.147 Python/2.7.18 Linux/5.10.118-111.515.amzn2.aarch64 botocore/1.18.6]", "requestParameters": { "Host": "s3.ap-northeast-1.amazonaws.com" }, "responseElements": null, "additionalEventData": { "SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "pDzNkahMJYN5k0pSHFUyAsMCPq8chu1it5UWuqT7S//x1s72py7h0oDh2eY0lqbejET56k8ighU=", "bytesTransferredOut": 5391 }, "requestID": "6P0XPKQ7PA6T1A1K", "eventID": "e939f3aa-a258-4227-888e-ba418a0d7efb", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "123456789012", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.ap-northeast-1.amazonaws.com" } }
NAT Gateway の EIP
IAM アクセスキー編
AmazonS3ReadOnlyAccess
ポリシーをアタッチした IAMユーザーを作成し、IAM アクセスキーを発行しました。EC2 は IAM ロールを設定せず、ここで発行した IAM アクセスキーを利用する構成を取ります。
パブリックサブネットの EC2 の場合
認証情報を EC2 に書き込み、IAM アクセスキーが EC2 上に保存しました。S3 バケットへのアクセス経路は Internet Gateway です。Internet Gateway へのルートを設定したサブネット上で EC2 には パブリックIP を付与しています。
[ec2-user@ip-10-0-1-232 ~]$ aws configure AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY Default region name [None]: ap-northeast-1 Default output format [None]: json
IAM アクセスキーに付与された権限で S3 バケットの一覧を取得(ListBuckets
)することができました。
[ec2-user@ip-10-0-1-232 ~]$ aws s3 ls | grep abashiri 2022-04-08 10:37:53 abashiri-image 2022-04-08 10:37:52 abashiri-image-log
CloudTrail から ListBuckets
イベントを確認します。ユーザー名から IAMアクセスキーの元のユーザー名を確認することができます。IAM ロールのときとは異なり、EC2 インスタンス ID は確認できませんでした。
個人的な見どころ
- IAM ユーザー名(
aeecess-key-on-ec2
)を確認できる - アクセス元のソースIP(
52.197.156.173
)は EC2 のパブリック IP であった
{ "eventVersion": "1.08", "userIdentity": { "type": "IAMUser", "principalId": "AIDAQ4BT4DHFPP4W7TSKU", "arn": "arn:aws:iam::123456789012:user/access-key-on-ec2", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "access-key-on-ec2" }, "eventTime": "2022-06-27T06:55:24Z", "eventSource": "s3.amazonaws.com", "eventName": "ListBuckets", "awsRegion": "ap-northeast-1", "sourceIPAddress": "52.197.156.173", "userAgent": "[aws-cli/1.18.147 Python/2.7.18 Linux/5.10.118-111.515.amzn2.aarch64 botocore/1.18.6]", "requestParameters": { "Host": "s3.ap-northeast-1.amazonaws.com" }, "responseElements": null, "additionalEventData": { "SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "5OleDo0vLGBwP4/ly62pWv1kLmBCOw3k9L9dPjHE6keZuRJaD1zia8hcm3DuhjuQaUP446jAJUg=", "bytesTransferredOut": 5391 }, "requestID": "YJK57XN5ZFW2B0PH", "eventID": "46651a03-4bed-4b03-b4c0-cbfb905b4a4d", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "123456789012", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.ap-northeast-1.amazonaws.com" } }
EC2 のパブリック IP アドレス
念のため、EC2 からグローバル IP を確認しました。間違いなく S3 バケットにアクセスした元の IP がソース IP と記録される様です。
[ec2-user@ip-10-0-1-232 ~]$ curl https://ifconfig.me 52.197.156.173
わかったこと
EC2 のパブリック IP がsourceIPAddress
表示されるため、EC2 インスタンスの特定はできないまでも EIP から辿ればアクセス元の EC2 インスタンスを特定することは可能。
プライベートサブネットの EC2 の場合
同様に認証情報を EC2 に書き込み、IAM アクセスキーが EC2 上に保存しました。S3 バケットへのアクセス経路は NAT Gateway を経由してアクセスします。NAT Gateway へのルートを設定したサブネット上で起動している EC2 です。
パブリックサブネットで検証した EC2 を踏み台に利用してアクセスしました。同様に IAM アクセスキーに付与された権限で S3 バケットの一覧を取得(ListBuckets
)することができました。
[ec2-user@ip-10-0-17-225 ~]$ aws s3 ls | grep abashiri 2022-04-08 10:37:53 abashiri-image 2022-04-08 10:37:52 abashiri-image-log
個人的な見どころ
- IAM ユーザー名(
aeecess-key-on-ec2
)を確認できる - アクセス元のソースIP(
54.150.188.89
)は NAT Gateway の EIP であった
{ "eventVersion": "1.08", "userIdentity": { "type": "IAMUser", "principalId": "AIDAQ4BT4DHFPP4W7TSKU", "arn": "arn:aws:iam::123456789012:user/access-key-on-ec2", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "access-key-on-ec2" }, "eventTime": "2022-06-27T07:06:53Z", "eventSource": "s3.amazonaws.com", "eventName": "ListBuckets", "awsRegion": "ap-northeast-1", "sourceIPAddress": "54.150.188.89", "userAgent": "[aws-cli/1.18.147 Python/2.7.18 Linux/5.10.118-111.515.amzn2.aarch64 botocore/1.18.6]", "requestParameters": { "Host": "s3.ap-northeast-1.amazonaws.com" }, "responseElements": null, "additionalEventData": { "SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "22aQ5pD3JaEQNdwI6ziYBW1gNVlRvKSax9JBZgKYw+g1DWWkNZ5hbeyEz3AqZGhijmDUmSYc4+c=", "bytesTransferredOut": 5391 }, "requestID": "NK5TSRSJNE1KJZGE", "eventID": "9911af24-f5fb-4d27-b828-4d6d78c2733d", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "123456789012", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.ap-northeast-1.amazonaws.com" } }
NAT Gateway の EIP
念のため、EC2 からグローバル IP を確認しました。同様に S3 バケットにアクセスした元の IP がソース IP と記録される様です。
[ec2-user@ip-10-0-17-225 ~]$ curl https://ifconfig.me 54.150.188.89
わかったこと
アクセス元の IP(sourceIPAddress
)に NAT Gateway の EIP が表示されるため、同 NAT Gateway を経由する EC2 インスタンス が複数台ある場合は、CloudTrail のひとつのイベントログから EC2 インスタンスを特定することはできない。
VPC エンドポイント Gateway 型の場合
Gateway 型の VPC エンドポイントはよく利用されていると思います。VPC エンドポイントを設定し同様の手順を実施しイベントログを確認します。
個人的な見どころ
- IAM ユーザー名(
aeecess-key-on-ec2
)を確認できる sourceIPAddress
には EC2 のプライベート IP が表示されるvpcEndpointId
で経由してきた VPC エンドポイントを確認できる
パブリックサブネット の EC2 からアクセスしたログ
{ "eventVersion": "1.08", "userIdentity": { "type": "IAMUser", "principalId": "AIDAQ4BT4DHFPP4W7TSKU", "arn": "arn:aws:iam::123456789012:user/access-key-on-ec2", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "access-key-on-ec2" }, "eventTime": "2022-06-27T11:43:10Z", "eventSource": "s3.amazonaws.com", "eventName": "ListBuckets", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10.0.1.232", "userAgent": "[aws-cli/1.18.147 Python/2.7.18 Linux/5.10.118-111.515.amzn2.aarch64 botocore/1.18.6]", "requestParameters": { "Host": "s3.ap-northeast-1.amazonaws.com" }, "responseElements": null, "additionalEventData": { "SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "V5mPuZ9gO9chY7ij2N4YDiFCmIP3crAE23hdsjJIjnTo9IM17K7S3+3jlTyQ5Jlc0MyNCdS1BO4=", "bytesTransferredOut": 5391 }, "requestID": "ZZG0ZHDYDQKB2VKE", "eventID": "78a65258-0d6d-4147-bb50-e1ab845b9566", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "123456789012", "vpcEndpointId": "vpce-04c1f50dba315db84", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.ap-northeast-1.amazonaws.com" } }
プライベートサブネット の EC2 からアクセスしたログ
{ "eventVersion": "1.08", "userIdentity": { "type": "IAMUser", "principalId": "AIDAQ4BT4DHFPP4W7TSKU", "arn": "arn:aws:iam::123456789012:user/access-key-on-ec2", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "access-key-on-ec2" }, "eventTime": "2022-06-27T11:43:48Z", "eventSource": "s3.amazonaws.com", "eventName": "ListBuckets", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10.0.17.225", "userAgent": "[aws-cli/1.18.147 Python/2.7.18 Linux/5.10.118-111.515.amzn2.aarch64 botocore/1.18.6]", "requestParameters": { "Host": "s3.ap-northeast-1.amazonaws.com" }, "responseElements": null, "additionalEventData": { "SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "j10MVy30v+tXJhVJC3m9AZDX4pA4P67QGnOkbQ+daCjx7VGGbvHnXd4BwcaMSO+xeQqow1HQaro=", "bytesTransferredOut": 5391 }, "requestID": "JTPF3BX69A6HYWE3", "eventID": "e68aa472-3862-46b9-b6c1-74abd9ac7e36", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "123456789012", "vpcEndpointId": "vpce-04c1f50dba315db84", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.ap-northeast-1.amazonaws.com" } }
VPC エンドポイント ID
わかったこと
アクセス元の IP(sourceIPAddress
)に EC2 のプライベート IP が表示されるため EC2 の特定が可能になる。
想定と異なった点
Gateway エンドポイントを経由して S3 バケットへのアクセスはパブリック IP が使用され、CloudTrail のソース IP は EC2 の EIP か、NAT Gateway の EIP になると想定していました。実際の結果は CloudTrail のアクセス元の IP は EC2 のプライベート IP アドレスでした。
AWS PrivateLink for Amazon S3 - Amazon Simple Storage Service
まとめ
S3 の API(ListBuckets
)をコールしたときのイベントログからでは、IAM アクセスキーかつ、NAT Gateway 経由のイベントログからのソース表示だけは EC2 を特定することができない。他の IAM アクセスキーのケースでも EC2 のインスタンス ID が直接わかるわけではなく、IP アドレスから追いかけて確認する必要がある。
Credential | サブネット | VPC Endpoint Gateway Type | ユーザー名の表示 | ソース IP の表示 |
---|---|---|---|---|
IAM ロール | Public | なし | EC2 の インスタンスID | EC2 の Public IP |
IAM ロール | Private | なし | EC2 の インスタンスID | NAT Gateway の EIP |
IAM アクセスキー | Public | なし | IAM ユーザー名 | EC2 の Public IP |
IAM アクセスキー | Private | なし | IAM ユーザー名 | NAT Gateway の EIP |
IAM アクセスキー | Public | あり | IAM ユーザー名 | EC2 の Private IP |
IAM アクセスキー | Private | あり | IAM ユーザー名 | EC2 の Private IP |
おわりに
収穫は IAMアクセスキーを使った EC2 では インスタンス ID が表示されないことと、VPC エンドポイントの Gateway 型を経由すると アクセス元がプライベート IP になるということでした。それと、IAM アクセスキーが埋め込まれている EC2 をこの方法で見つけるには非効率ということがわかりました。
非常に地味な検証で時間もかかるので同じことしようと思った方の参考になれば幸いです。